﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Infraestructure.Data.Core;
using Domain.MainModule.Entities;
using Domain.MainModule.Branches;
using Domain.MainModule.GroupBranches;
using Domain.Core.Specification;
using Infraestructure.Data.MainModule.UnitOfWork;
using System.Globalization;
using Infraestructure.Data.MainModule.Resources;
using Infraestructure.CrossCutting.Logging;

namespace Infraestructure.Data.MainModule.Repositories
{
    public class BranchRepository: Repository<Branch>, IBranchRepository
    {
        #region Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="unitOfWork">IMainModuleUnitOfWork dependency, intented to be resolved with IoC</param>
        /// <param name="traceManager">ITraceManager context, intended to be resolved wiht IoC</param>
        public BranchRepository(IMainModuleUnitOfWork unitOfWork, ITraceManager traceManager) : base(unitOfWork, traceManager) { }

        #endregion Constructor

        #region private methods

        private Branch FindBranchBySpecification(ISpecification<Branch> specification)
        {
            //validate specification
            if (specification == (ISpecification<Branch>)null)
            {
                throw new ArgumentNullException("specification");
            }

            IMainModuleUnitOfWork context = this.UnitOfWork as IMainModuleUnitOfWork;

            if (context != null)
            {
                return context.Branches.Where(specification.SatisfiedBy()).SingleOrDefault();
            }
            else
                throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InvariantCulture,
                                                                Messages.exception_InvalidStoreContext,
                                                                this.GetType().Name));
        }

        #endregion

        #region IBranchRepository implementations

        public IEnumerable<Branch> FindBranches(ISpecification<Branch> specification)
        {
            //validate specification
            if (specification == (ISpecification<Branch>)null)
            {
                throw new ArgumentNullException("specification");
            }

            IMainModuleUnitOfWork context = this.UnitOfWork as IMainModuleUnitOfWork;

            if (context != null)
            {
                return context.Branches.Where(specification.SatisfiedBy());
            }
            else
            {
                throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InvariantCulture,
                                                                Messages.exception_InvalidStoreContext,
                                                                this.GetType().Name));
            }

        }

        public Branch FindBranch(ISpecification<Branch> specification)
        {
            return this.FindBranchBySpecification(specification);
        }

        #endregion
    }
}
